package org.jasig.cas.client.authentication.sdk;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jasig.cas.client.ssl.HttpURLConnectionFactory;
import org.jasig.cas.client.ssl.HttpsURLConnectionFactory;
import org.jasig.cas.client.util.CommonUtils;

/**
 * 
 * @author CreGu
 * 
 */
public class ApiCaller {
	protected static final org.slf4j.Logger log = org.slf4j.LoggerFactory
			.getLogger(ApiCaller.class);

	private String casServerUrlPrefix;
	private String urlSuffix;
	private String serverUrl;
	private HttpURLConnectionFactory urlConnectionFactory = new HttpsURLConnectionFactory();
	private ApiRpc rpc;

	private static ApiCaller caller;

	private ApiCaller(String casServerUrlPrefix, String serverUrl,
			HttpURLConnectionFactory urlConnectionFactory) {
		this.casServerUrlPrefix = casServerUrlPrefix;
		this.serverUrl = serverUrl;
		this.urlConnectionFactory = urlConnectionFactory;

		this.rpc = new ApiRpc(this);
	}

	public static ApiCaller getInstance() {
		if (caller == null)
			throw new IllegalStateException("未初始化，请使用newInstance()建立实例");
		return caller;
	}

	public static ApiCaller newInstance(String casServerUrlPrefix,
			String serverUrl, HttpURLConnectionFactory urlConnectionFactory) {
		caller = new ApiCaller(casServerUrlPrefix, serverUrl,
				urlConnectionFactory);
		return caller;
	}

	public String apiCall(Map<String, String> urlParameters)
			throws MalformedURLException {
		final String requestUrl = constructUrl(urlParameters);

		return CommonUtils.getResponseFromServer(new URL(requestUrl),
				getUrlConnectionFactory(), SdkUtil.getDefaultCharset());
	}

	protected final String constructUrl(Map<String, String> urlParameters) {
		urlParameters.put("withoutLoginForm", "true");
		urlParameters.put("service", this.serverUrl);
		urlParameters.put("apiKey", "api");

		return SdkUtil.construcUrl(this.casServerUrlPrefix, this.urlSuffix,
				urlParameters);
	}

	public String getUrlSuffix() {
		return urlSuffix;
	}

	public void setUrlSuffix(String urlSuffix) {
		this.urlSuffix = urlSuffix;
	}

	public String getServerUrl() {
		return serverUrl;
	}

	public void setServerUrl(String serverUrl) {
		this.serverUrl = serverUrl;
	}

	public ApiRpc getRpc() {
		return rpc;
	}

	public HttpURLConnectionFactory getUrlConnectionFactory() {
		return urlConnectionFactory;
	}

	public void redirect(HttpServletRequest request,
			HttpServletResponse response, Map<String, String> params)
			throws IOException {
		String serverUrl = this.serverUrl;
		serverUrl += serverUrl.endsWith("/") ? request.getContextPath()
				.substring(1) : request.getContextPath();

		if (!serverUrl.endsWith("/"))
			serverUrl += "/";

		String casServerUrlPrefix = this.casServerUrlPrefix;
		casServerUrlPrefix += casServerUrlPrefix.endsWith("/") ? "login" : "/"
				+ "login";

		String redirectUrl = CommonUtils.constructRedirectUrl(
				casServerUrlPrefix, "service", response.encodeURL(serverUrl),
				false, true);
		redirectUrl += "&ticketGrantingTicketId="
				+ params.get(ApiRpc.TICKETGRANTINGTICKET);

		response.sendRedirect(redirectUrl);
	}
}
